package org.sunrise.game.game.logic.system;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import org.sunrise.game.common.db.entity.EntityServerData;
import org.sunrise.game.game.async.AsyncEventManager;
import org.sunrise.game.game.db.DbManager;
import org.sunrise.game.game.logic.ToolsUtils;
import org.sunrise.game.game.server.GameManager;

import java.util.HashMap;
import java.util.Map;

public class GameSystem {
    private static long lastSaveDbTime = System.currentTimeMillis(); //上次保存数据的时间
    private static final Map<String, BaseSystem> systems = new HashMap<>();

    private static void createSystems() {
        systems.put(ResetSystem.class.getSimpleName(), new ResetSystem());
    }

    @SuppressWarnings("unchecked")
    public static <T extends BaseSystem> T getSystem(Class<T> clazz) {
        return (T) systems.get(clazz.getSimpleName());
    }

    /**
     * GameSystem 初始化
     */
    public static void init() {
        createSystems();
        for (Map.Entry<String, BaseSystem> entry : systems.entrySet()) {
            entry.getValue().init();
        }
        load();
    }

    /**
     * GameSystem load db
     */
    public static void load() {
        for (Map.Entry<String, BaseSystem> entry : systems.entrySet()) {
            DbManager.getDbService().queryGetOneByParamsAsync((result -> {
                AsyncEventManager.addAsyncEvent(() -> {
                    if (result != null) {
                        EntityServerData serverData = new EntityServerData(result);
                        entry.getValue().setDataMap(JSON.parseObject(serverData.getData(), new TypeReference<Map<String, String>>() {}.getType()));
                        entry.getValue().load();
                    } else {
                        DbManager.getDbService().executeAsync("insert into `server_data` (server_id,name,data) values (?,?,?)", GameManager.getGameId(), entry.getKey(), JSON.toJSONBytes(entry.getValue().getDataMap()));
                    }
                    entry.getValue().setInitEnd(true);
                });
            }), "select * from `server_data` where `server_id` = ? and `name` = ?", GameManager.getGameId(), entry.getKey());
        }
    }

    /**
     * GameSystem save db
     */
    public static void save() {
        for (Map.Entry<String, BaseSystem> entry : systems.entrySet()) {
            entry.getValue().save();

            DbManager.getDbService().executeAsync("update `server_data` set `data` = ? where `server_id` = ? and `name` = ?",
                    JSON.toJSONBytes(entry.getValue().getDataMap()), GameManager.getGameId(), entry.getKey());
        }
    }

    /**
     * GameSystem 主心跳
     */
    public static void pulse() {
        long cur = System.currentTimeMillis();
        if (lastSaveDbTime + ToolsUtils.MINUTE_MILLS < cur) {
            lastSaveDbTime = cur;
            save();
        }
        for (Map.Entry<String, BaseSystem> entry : systems.entrySet()) {
            entry.getValue().pulse();
        }
    }

}
